import React, { useEffect, useState } from "react"; import { META } from "@consumet/extensions"; import Link from "next/link"; import Layout from "../../components/layout"; import Head from "next/head"; import { closestMatch } from "closest-match"; import Content from "../../components/hero/content"; import { getServerSession } from "next-auth/next"; import { authOptions } from "../api/auth/[...nextauth]"; import Image from "next/image"; export default function Himitsu({ info, color, episodeList, episode1, sessions, progress, status, lastPlayed, stall, }) { const [showText, setShowtext] = useState(false); const [load, setLoad] = useState(true); const [showAll, setShowAll] = useState(false); const [time, setTime] = useState(0); const episode = episodeList; const epi1 = episode1; const maxItems = 3; const nextAir = info.nextAiringEpisode; // console.log(time); useEffect(() => { if (nextAir) { setTime(convertSecondsToTime(nextAir.timeUntilAiring)); } function getBrightness(color) { const rgb = color.match(/\d+/g); return (299 * rgb[0] + 587 * rgb[1] + 114 * rgb[2]) / 1000; } // set the text color based on the background color function setTextColor(element) { const backgroundColor = getComputedStyle(element).backgroundColor; const brightness = getBrightness(backgroundColor); if (brightness < 128) { element.style.color = "#fff"; // white } else { element.style.color = "#000"; // black } } const elements = document.querySelectorAll(".dynamic-text"); elements.forEach((element) => { setTextColor(element); }); setLoad(false); }, [color, sessions, info.id]); return ( <> {info.title?.english || info.title.romaji}
{info ? (
{info.image && ( <>
image
)}
{/* MOBILE */}

{info.title.romaji || info.title.english}

Rate:

{info.rating}%

Format:

{info.type}

Status:

{info.status}

{/* {nextAir && (

Ep {nextAir.episode}:

{time}

)} */}
{epi1 && epi1[0] ? (

{" "} WATCH

) : (

{" "} WATCH

)}
{/* PC */}

{info.title?.english || info.title.romaji || info.title.native}

{episode && episode.length} Episodes
{info.releaseDate}
{info.rating}%
{info.type}
{info.status}
Sub | EN
{nextAir && (
Ep {nextAir.episode}: {time}
)}

Relations
{info.relations.length > maxItems && (
setShowAll(!showAll)} > {showAll ? "show less" : "show more"}
)}
{info.relations && info.relations .slice(0, showAll ? info.relations.length : maxItems) .map((relation, index) => { return (
{relation.id}
{relation.relationType}
{relation.title.romaji}
{relation.type}
); })}

Episodes

{status && ( <>
{status} status
)}
{load ? (

Loading...

) : episode ? ( episode.map((episode, index) => { return (

Episode {episode.number}

{episode.title && (

"{episode.title}"

)}
); }) ) : (

No Episodes Available

)}
) : (

404

{`> Woops.. I think we don't have that Anime :(`}

Return to search
)}
); } export async function getServerSideProps(context) { context.res.setHeader( "Cache-Control", "public, s-maxage=10, stale-while-revalidate=59" ); const session = await getServerSession(context.req, context.res, authOptions); const { id } = context.query; if (!id) { return { notFound: true, }; } const provider = new META.Anilist(); const [info, episodes] = await Promise.all([ fetch(`https://api.moopa.my.id/meta/anilist/info/${id[0]}`).then((res) => res.json() ), provider.fetchEpisodesListById(id[0]), ]); if (!info) { return { notFound: true, }; } let episodeList = episodes; let stall = false; if (episodes.length === 0) { const res = await fetch( `https://api.consumet.org/meta/anilist/info/${id[0]}?provider=9anime` ); const data = await res.json(); episodeList = data.episodes; stall = true; } let progress = null; let status = null; let lastPlayed = null; if (session) { const response = await fetch("https://graphql.anilist.co/", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ query: ` query ($username: String, $status: MediaListStatus) { MediaListCollection(userName: $username, type: ANIME, status: $status, sort: SCORE_DESC) { user { id name about (asHtml: true) createdAt avatar { large } statistics { anime { count episodesWatched meanScore minutesWatched } } bannerImage mediaListOptions { animeList { sectionOrder } } } lists { status name entries { id mediaId status progress score media { id status title { english romaji } episodes coverImage { large } } } } } } `, variables: { username: session?.user.name, }, }), }); const dat = await response.json(); // const resp = await fetch(`/api/get-user?userName=${session?.user.name}`); // const data = await resp.json(); lastPlayed = session?.user?.recentWatch?.filter( (item) => item.title.romaji === info.title.romaji )[0]?.episode; const prog = dat.data.MediaListCollection; const gat = prog.lists.map((item) => item.entries); const git = gat.map((item) => item.find((item) => item.media.id === parseInt(info.id)) ); const gut = git?.find((item) => item?.media.id === parseInt(info.id)); if (gut) { progress = gut?.progress; if (gut.status === "CURRENT") { status = "Watching"; } else if (gut.status === "PLANNING") { status = "Planned to watch"; } else if (gut.status === "COMPLETED") { status = "Completed"; } else if (gut.status === "DROPPED") { status = "Dropped"; } else if (gut.status === "PAUSED") { status = "Paused"; } else if (gut.status === "REPEATING") { status = "Rewatching"; } } } const color = { backgroundColor: `${info.color}` }; const epi1 = episodes.filter((epi) => epi.number === 1); const title = info.title?.userPreferred || "No Title"; return { props: { info: { ...info, title: { ...info.title, userPreferred: title, }, }, color, episodeList, episode1: epi1, sessions: session, progress: progress || null, status: status, lastPlayed: lastPlayed || null, stall, }, }; } function convertSecondsToTime(sec) { let days = Math.floor(sec / (3600 * 24)); let hours = Math.floor((sec % (3600 * 24)) / 3600); let minutes = Math.floor((sec % 3600) / 60); let time = ""; if (days > 0) { time += `${days}d `; } if (hours > 0) { time += `${hours}h `; } if (minutes > 0) { time += `${minutes}m `; } return time.trim(); }